package javafx.fxml.common;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 包装控制器对象
 *
 * 提供反射操作
 */
public class ControllerAdapter extends POJOAdapter{
    protected static final ConcurrentHashMap<Class<?>, Map<String,Field>> fieldCache = new ConcurrentHashMap<>();

    public ControllerAdapter(Object target) {
        super(target);
    }


    public Object getFliedValue(String flied) {
        Field field = findField(flied);
        field.setAccessible(true);
        try {
            return field.get(getTarget());
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private Field findField(String flied) {
        Map<String,Field> cache = fieldCache.get(getType());
        if(cache == null){
            cache = initFieldCache();
        }
        return cache.get(flied);
    }

    private synchronized  Map<String,Field> initFieldCache() {
        Map<String,Field> cache = fieldCache.get(getType());
        if(cache == null){
            cache = new HashMap<>();
            fieldCache.put(getType(), cache);

            for (Field field : getType().getDeclaredFields()) {
                cache.put(field.getName(),field);
            }
        }
        return cache;
    }

    public void setFliedValue(String flied,Object value){
        Field field = findField(flied);
        field.setAccessible(true);
        try {
            field.set(getTarget(),value);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public Object tryGet(String field){
        try {
            return get(field);
        }catch (Exception e){
            return getFliedValue(field);
        }
    }

    public void trySet(String field,Object value){
        try {
            set(field,value);
        }catch (Exception e){
            setFliedValue(field, value);
        }
    }
}
